import cv2
import time
from datetime import datetime
import os
import glob
import os


def check_and_create_path(path):
    try:
        if not os.path.exists(path):
            os.makedirs(path)
            print(f"Directory {path} created.")
        else:
            print(f"Directory {path} already exists.")
    except OSError as error:
        print(f"Failed to create directory {path}. Error: {error}")


def delete_oldest_file_if_needed(directory, file_count_limit=100):
    # 获取指定文件夹内所有文件的列表，排除文件夹
    files = [f for f in glob.glob(os.path.join(directory, '*')) if os.path.isfile(f)]

    # 检查文件数量是否超过限制q
    if len(files) > file_count_limit:
        # 按修改时间排序文件
        files_with_timestamp = [(f, os.path.getmtime(f)) for f in files]
        oldest_file = min(files_with_timestamp, key=lambda x: x[1])[0]  # 获取最早修改的文件

        # 删除最早的文件
        print(f"文件数量超出限制，删除文件: {oldest_file}")
        os.remove(oldest_file)


def faceSign(gray):
    global x, y, w, h
    # 进行人脸检测
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    # 在检测到的每张脸上画框
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)


def moveSign(frame, gray, before):
    # 计算当前画面与移动平均线的差分
    cv2.accumulateWeighted(gray, before, 0.5)
    frameDelta = cv2.absdiff(gray, cv2.convertScaleAbs(before))
    # 将差分图二值化
    thresh = cv2.threshold(frameDelta, 3, 255, cv2.THRESH_BINARY)[1]
    # 提取轮廓
    contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]

    # 遍历所有轮廓，描点，框选
    for c in contours:
        if cv2.contourArea(c) < 100:  # 根据需要调整这个阈值
            continue
        (x, y, w, h) = cv2.boundingRect(c)
        # 绘制矩形框
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)


# 视频保存的基础路径
VIDEO_PATH = 'E:/camera/video/'
check_and_create_path(VIDEO_PATH)

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 初始化摄像头
cap = cv2.VideoCapture(0)  # 0 通常是默认摄像头的标识
# 设置视频编解码器，这里使用MJPG，您也可以根据需要选择其他编解码器，如XVID等
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# 获取视频的帧率，这里假设为30fps
fps = 30.0

# 获取视频的尺寸（宽度和高度）
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# 初始化第一个VideoWriter
videoName = datetime.now().strftime('%Y%m%d_%H%M%S')
video_filename = f"{videoName}.avi"
video_file_path = VIDEO_PATH + video_filename
out = cv2.VideoWriter(video_file_path, fourcc, fps, (frame_width, frame_height))
print(f"开始录制新视频: {video_file_path}")

start_time = time.time()
before = None

# 替换为你要检查的文件夹路径
delete_oldest_file_if_needed(VIDEO_PATH)

while True:
    # 逐帧捕获
    ret, frame = cap.read()

    # 如果正确读取帧，ret为True
    if not ret:
        print("无法接收帧，请退出")
        break

    # 检查是否达到3分钟，如果是，则重新初始化VideoWriter
    current_time = time.time()
    if current_time - start_time >= 180:  # 180秒等于3分钟
        # 关闭当前的VideoWriter
        out.release()

        # 替换为你要检查的文件夹路径
        delete_oldest_file_if_needed(VIDEO_PATH)

        # 重置视频计数器和文件名
        videoName = datetime.now().strftime('%Y%m%d_%H%M%S')
        video_filename = f"{videoName}.avi"
        video_file_path = VIDEO_PATH + video_filename

        # 重新初始化VideoWriter
        out = cv2.VideoWriter(video_file_path, fourcc, fps, (frame_width, frame_height))
        print(f"开始录制新视频: {video_file_path}")

        # 重置计时器
        start_time = current_time

    # 转成灰度图
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 人脸标记
    faceSign(gray)

    # # 移动物体标记
    # if before is None:
    #     before = gray.astype("float")
    # else:
    #     moveSign(frame, gray, before)

    # 显示结果图像
    cv2.imshow('Face Detection', frame)

    # 将当前帧写入视频文件
    out.write(frame)

    # ESC键退出程序
    if cv2.waitKey(1) == 27: break

# 释放资源
cap.release()
out.release()  # 确保最后释放VideoWriter
# 关闭所有OpenCV窗口
cv2.destroyAllWindows()
